[% setvar title Better constants and constant folding %]
<div id="archive-notice">
    <h3>This file is part of the Perl 6 Archive</h3>
    <p>To see what is currently happening visit <a href="http://www.perl6.org/">http://www.perl6.org/</a></p>
</div>
<div class='pod'>
<a name='TITLE'></a><h1>TITLE</h1>
<p>Better constants and constant folding</p>
<a name='VERSION'></a><h1>VERSION</h1>
<pre>  Maintainer: John Siracusa &lt;<a href='mailto:siracusa@mindspring.com'>siracusa@mindspring.com</a>&gt;
  Date: 15 Aug 2000
  Last Modified: 16 Aug 2000
  Mailing List: <a href='mailto:perl6-language@perl.org'>perl6-language@perl.org</a>
  Number: 113
  Version: 2
  Status: Retired</pre>
<a name='STATUS'></a><h1>STATUS</h1>
<p>This has been integrated with RFC 83.</p>
<p>This RFC was retracted by the author on 16 Aug 2000.</p>
<a name='ABSTRACT'></a><h1>ABSTRACT</h1>
<p>There are many ways to use named &quot;constants&quot; in Perl, but they all have
drawbacks: runtime initialization costs, the extra overhead of loading
another module, the inability to use the constants in certain situations,
and so on.</p>
<p>Constants should be first-class citizens in Perl, and should be constant
folded with a vengeance by a clever compiler.</p>
<a name='DESCRIPTION'></a><h1>DESCRIPTION</h1>
<p>An ideal Perl constant can be used anywhere that a Perl variable of the
same type can be used: a constant scalar can be used in place of any
scalar, a constant array can be used in place of any array, and so on.
These constants should not incur runtime inefficiencies or undue
compile-time overhead.  Performance should be should be exactly as if the
data was hard-coded in place.</p>
<a name='IMPLEMENTATION'></a><h1>IMPLEMENTATION</h1>
<p>The simplest solution is something like:</p>
<pre>    constant $PI = 3.14159265;</pre>
<p>This looks shockingly similar to the current, much maligned (by me, anyway)
constant module:</p>
<pre>    use constant PI =&gt; 3.14159265;</pre>
<p>but the former has many syntactic advantages.  First, there's no &quot;use&quot;
directive to reveal the constant's second-class citizenship.  Second, it
uses the assignment operator instead of the &quot;fancy comma.&quot;  Third, context
is determined by the left-hand-side of the assignment operator instead of
always being forced into list context.</p>
<p>Using these constants is simple.  They behave just like variables of the
same type.</p>
<pre>    print &quot;Would you like some apple $PI?&quot;; # A constant string</pre>
<p>That whole string is converted to a single constant at compile time.
Collections behave in a similar manner:</p>
<pre>    constant @FISH = (1, 2, 'red', 'blue');
    
    print @FISH;   # prints &quot;12redblue&quot;
    print &quot;@FISH&quot;; # prints &quot;1 2 red blue&quot;

    print &quot;$FISH[2] head&quot;; # prints &quot;red head&quot;</pre>
<p>Again, each argument to <code>print</code> is converted to a constant string at
compile time.</p>
<p>Modification of a constant is a compile-time error:</p>
<pre>    $PI = 5;           # Bzzt!
    $PI =~ s/\.\d+$//; # Sorry
    $#FISH = 15;       # Nice try</pre>
<p>The <code>constant</code> keyword should work when combined with <code>my</code> and <code>our</code>:</p>
<pre>    package Foo;
    
    our constant $GOO = 5;
    
    if(...)
    {
      my constant $GOO = 10;
      
      print $GOO; # Prints 10
    }</pre>
<p>As an added implementation bonus, &quot;constant methods&quot; should be supported
in the same way that &quot;constant subroutines are now.</p>
<pre>    package MyConstants;
    constant $PI = 3.14159265;

    package MyClass;
    ...
    sub method { $MyConstants::PI }
    
    package MyLib;
    ...
    sub func { $MyConstants::PI } # Shouldn't have to be sub func() ...</pre>
<p>Both <code>method()</code> and <code>func()</code> should know that they return constants,
and the compiler should optimize them away whenever possible, even without
explicit hints like an empty &quot;()&quot; prototype after <code>func</code>.  Yes, there
are issues with turning a method call into a constant at compile time, but
it's possible if Perl can determine with certainty that <code>MyClass::method</code>
is the actual code that will be executed by an object or class method call.
Example:</p>
<pre>    my $obj = MyClass-&gt;new;
    
    print $obj-&gt;method();    # Converted to the constant 3.14159265
    print MyClass-&gt;method(); # Ditto</pre>
<p>Again, this magic is accomplished by a clever compiler that does not need
this type of help:</p>
<pre>    my MyClass $obj = MyClass-&gt;new; # Not necessary, ideally</pre>
<p>As should be clear by now, I'm not too familiar with the perl internals
that are required to support this stuff.  It just &quot;seems possible&quot; to me.
And hey, there are no &quot;perl internals&quot; to speak of yet in a &quot;clean-sheet&quot;
implementation, right?</p>
<a name='REFERENCES'></a><h1>REFERENCES</h1>
<p>Perl's <code>constant</code> pragma documentation.</p>
</div>
